import domain from '@/utils/domain';
import axios, { AxiosInstance, AxiosResponse } from 'axios';
import { ElMessage, ElLoading } from 'element-plus';

import { store } from '@/store';
import router from '@/router';
import storage from '@/utils/storage';

// interface Querypath {
//     page?: string;
//     from?: string;
// }

const realCreate = axios.prototype.constructor.create;

const httpStatusMessage = {
    200: '服务器成功返回请求的数据',
    201: '新建或修改数据成功。',
    202: '一个请求已经进入后台排队（异步任务）',
    204: '删除数据成功。',
    400: '发出的请求有错误，服务器没有进行新建或修改数据的操作。',
    401: '用户没有权限（令牌、用户名、密码错误）。',
    403: '用户得到授权，但是访问是被禁止的。',
    404: '发出的请求针对的是不存在的记录，服务器没有进行操作',
    406: '请求的格式不可得。',
    410: '请求的资源被永久删除，且不会再得到的。',
    422: '当创建一个对象时，发生一个验证错误。',
    500: '服务器发生错误，请检查服务器',
    502: '网关错误',
    503: '服务不可用，服务器暂时过载或维护',
    504: '网关超时'
};

let loading: any;
let isRefreshing = false;
export const startLoading = () => {
    loading = ElLoading.service({
        lock: true,
        text: '加载中....',
        background: 'rgba(0, 0, 0, 0.7)'
    });
};
export const endLoading = () => {
    loading?.close();
};
let needLoadingRequestCount = 0;
export function showFullScreenLoading() {
    if (needLoadingRequestCount === 0) startLoading();
    needLoadingRequestCount++;
}
export function tryHideFullScreenLoading() {
    if (needLoadingRequestCount < 0) return;
    needLoadingRequestCount--;
    if (needLoadingRequestCount === 0) endLoading();
}
/**
 *
 * @param config
 *
 * type 0  不携带cookie
 *  type 1 返回阿里云数据 没有code返回
 *  type 2 form表单
 * @returns
 */
// 根据配置初始化Axios 实例
const newInstance: any = (): AxiosInstance => {
    const CancelToken = axios.CancelToken;
    const source = CancelToken.source();
    // const axiosService: AxiosInstance = axios.create({
    const axiosService: AxiosInstance = realCreate({
        baseURL: domain.BASE_API_URL,
        headers: { 'X-Requested-With': 'XMLHttpRequest', 'Content-Type': 'application/json' },
        timeout: 30000,
        responseType: 'json',
        noNeedLoading: false
    });
    axiosService.interceptors.request.use(
        (config: any) => {
            if (!config['noNeedLoading']) {
                showFullScreenLoading();
            } else {
                const apiList = store.getters['user/getApiList'];
                if (apiList.length && apiList.includes(config.url)) {
                    startLoading();
                    if (apiList.length > 2) {
                        const index = apiList.findIndex((item: any) => item === config.url);
                        const resList = apiList.reduce((pre, cur, ind) => {
                            if (ind !== index) {
                                pre.push(cur);
                            }
                            return pre;
                        }, []);
                        store.commit('user/setApiList', resList);
                        config.headers['isDeal_'] = true;
                    }
                }
            }
            config.cancelToken = source.token;
            const token = store.getters['user/getToken'];
            if (token) {
                config.headers['auth-token'] = token;
            }
            // 发送短信验证携带cookie
            if (config.type === 0) {
                config.withCredentials = true;
            }
            // formData表单
            if (config.type === 2) {
                config.headers['Content-Type'] = 'multipart/form-data;';
                // 上传到阿里云 不需要传递 token和cookie
                if (config.oss) {
                    delete config.headers['auth-token'];
                }
            }
            return config;
        },
        error => {
            ElMessage('请求超时!');
            // 对请求错误做些什么
            return Promise.reject(error);
        }
    );
    axiosService.interceptors.response.use(
        (response: AxiosResponse) => {
            //拦截响应，做统一处理
            if (!response.config['noNeedLoading']) {
                tryHideFullScreenLoading();
            } else {
                const apiList = store.getters['user/getApiList'];
                if (!response.config.headers.isDeal_ && apiList.length === 1 && apiList.includes(response.config.url)) {
                    endLoading();
                    store.commit('user/setApiList', []);
                } else if (
                    !response.config.headers.isDeal_ &&
                    apiList.length === 2 &&
                    apiList.includes(response.config.url)
                ) {
                    const index = apiList.findIndex((item: any) => item === response.config.url);
                    const resList = apiList.reduce((pre, cur, ind) => {
                        if (ind !== index) {
                            pre.push(cur);
                        }
                        return pre;
                    }, []);
                    store.commit('user/setApiList', resList);
                }
            }
            const statusMsg = httpStatusMessage[response.status];
            const to = router.currentRoute.value;
            const query = Object.assign({}, to.query);
            if (!query.page) {
                query.page = to.fullPath;
                query.from = 'response';
            }
            // 请求阿里云返回参数
            if (response.config.type === 1) {
                return Promise.resolve(response.data);
            }
            if (response.status >= 200 && response.status < 300) {
                const code = response.data.code || response.data.status || 0;
                if (code !== 200 && code !== 0) {
                    endLoading();
                    store.commit('user/setApiList', []);
                }
                if (code === 200 || code === 0) {
                    return Promise.resolve(response.data.data || response.data.result);
                } else if (code === 401) {
                    localStorage.setItem('abnormal', '1');
                    store.commit('user/setUserToken', '');
                    store.commit('user/setAccountInfo', null);
                    storage.remove('power-code');
                    storage.remove('zw-scrm-state');
                    storage.remove('add_customer_select');
                    storage.remove('add_customer_optional');
                    store.commit('user/clearUser');
                    store.commit('menu/clearMenu');
                    sessionStorage.clear();
                    localStorage.clear();
                    if (!isRefreshing) {
                        isRefreshing = true;
                        ElMessage.error('用户登录已过期，请重新登录');
                    }
                    router.push({ path: '/login' });
                    return Promise.reject(response.data);
                } else if (code === 406) {
                    ElMessage.error(response.data.msg);
                    store.commit('user/setUserToken', '');
                    store.commit('user/setAccountStatus', code);
                    store.commit('user/setAccountInfo', null);
                    storage.remove('power-code');
                    storage.remove('zw-scrm-state');
                    storage.remove('add_customer_select');
                    storage.remove('add_customer_optional');
                    store.commit('user/clearUser');
                    store.commit('menu/clearMenu');
                    sessionStorage.clear();
                    localStorage.clear();
                    router.push({ path: '/login' });
                    return Promise.reject(response.data);
                } else if (code === 501) {
                    ElMessage.error(response.data.msg);
                    return Promise.reject(response.data);
                } else if (code === 500) {
                    ElMessage.error(response.data.msg || '系统繁忙，请稍后再试');
                    return Promise.reject(response.data.msg);
                } else if (code === 10000) {
                    return Promise.reject(response.data);
                } else if (code === 10001) {
                    return Promise.reject(response.data);
                } else if (code === 1033) {
                    ElMessage.warning(response.data.msg);
                    return Promise.reject(response.data.msg);
                } else if (code === 1034) {
                    ElMessage.warning(response.data.msg);
                    return Promise.reject(response.data.msg);
                } else if (code == 5001) {
                    ElMessage.warning(response.data.msg);
                } else if (code === 51042) {
                    return Promise.reject(response.data);
                } else if ([52001, 52002, 52005, 53002].includes(code)) {
                    ElMessage.warning(response.data.msg);
                    return Promise.reject(response.data);
                } else if (code === 52003) {
                    ElMessage.warning(response.data.msg);
                    return Promise.reject(response.data);
                } else if (code === 1500) {
                    return Promise.reject(response.data);
                } else if (code === 72000) {
                    return Promise.reject(response.data);
                } else if ([620018].includes(code)) {
                    return Promise.reject(response.data);
                } else {
                    return Promise.reject(response.data.msg);
                }
            } else {
                ElMessage.error(statusMsg);
                endLoading();
                store.commit('user/setApiList', []);
            }
        },
        error => {
            tryHideFullScreenLoading();
            endLoading();
            store.commit('user/setApiList', []);
            const err = JSON.parse(JSON.stringify(error));
            const errorMsg = httpStatusMessage[err.status] as string;

            // console.error(errorMsg, '---错误信息状态码---', err.status)
            return Promise.reject(err);
        }
    );
    return axiosService;
};

const defaultService = newInstance();

export { newInstance };

export default defaultService;
